package com.errol.batchprocessor.employeeaddition.advisorimpl.demand;

import com.baomidou.mybatisplus.mapper.Condition;
import com.renjia.dao.*;
import com.renjia.entity.BusDemandEmployee;
import com.renjia.entity.BusDemandEmployeeTemp;
import com.renjia.entity.CoreEmployeeImportBatch;
import com.renjia.enums.*;
import com.renjia.pojo.AutoCompleteFlagParser;
import com.renjia.service.CoreEmployeeImportBatchService;
import com.renjia.service.generic.log.LogService;
import com.renjia.service.generic.middleware.batchprocessor.payload.AbstractBatchPayload;
import com.renjia.service.generic.support.customer.CustomerChannelSupportService;
import com.renjia.service.generic.support.employee.BankCardSupportService;
import com.renjia.service.generic.support.employee.EmployeeCustomerSupportService;
import com.renjia.service.generic.support.employee.EmployeeSupportService;
import com.renjia.service.integration.threeelements.ThreeElementsService;
import com.renjia.service.module.employee.AgreementSigningService;
import com.renjia.service.module.employeeaddition.advisorimpl.EmployeeAdvisorTypeEnum;
import com.renjia.service.module.employeeaddition.advisorimpl.common.AbstractEmployeeAdvisorImpl;
import com.renjia.service.module.employeeaddition.advisorimpl.common.EmployeeAutoCompleteModifier;
import com.renjia.service.module.employeeaddition.advisorimpl.demand.payload.DemandEmployeeBatchPayload;
import com.renjia.service.module.employeeaddition.advisorimpl.demand.payload.DemandEmployeePiecePayload;
import com.renjia.service.module.employeeaddition.advisorimpl.demand.payload.DemandEmployeeSinglePayload;
import com.renjia.service.module.messagecenter.MsgCenterSendService;
import com.renjia.util.EpayCallingService;
import org.springframework.lang.NonNull;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * 接单导入人员实现
 *
 * @author zhang xiao bin
 * @version v1.0
 * @date 2021/02/26
 * @since v5.0.6
 **/
@Service
public class DemandEmployeeAdvisorImpl
        extends AbstractEmployeeAdvisorImpl<Object, BusDemandEmployeeTemp, DemandEmployeeBatchPayload, DemandEmployeePiecePayload, DemandEmployeeSinglePayload>
        implements EmployeeAutoCompleteModifier<Object, BusDemandEmployeeTemp, DemandEmployeeBatchPayload, DemandEmployeePiecePayload, DemandEmployeeSinglePayload, DemandEmployeeAdvisorImpl> {

    protected final BusDemandMapper busDemandMapper;
    protected final BusDemandEmployeeMapper busDemandEmployeeMapper;
    protected final BusDemandEmployeeTempMapper busDemandEmployeeTempMapper;
    private final MsgCenterSendService msgCenterSendService;

    public DemandEmployeeAdvisorImpl(CoreEmployeeImportBatchService coreEmployeeImportBatchService,
                                     CoreEmployeeMapper coreEmployeeMapper, CoreEmployeeCustomerMapper coreEmployeeCustomerMapper,
                                     CoreUserBankMapper coreUserBankMapper, CoreAgreementDetailMapper coreAgreementDetailMapper, ThreeElementsService threeElementsService,
                                     EmployeeSupportService employeeSupportService, EmployeeCustomerSupportService employeeCustomerSupportService,
                                     BankCardSupportService bankCardSupportService, CustomerChannelSupportService customerChannelSupportService,
                                     AgreementSigningService agreementSigningService, EpayCallingService epayCallingService, LogService logService,
                                     BusDemandMapper busDemandMapper,
                                     BusDemandEmployeeMapper busDemandEmployeeMapper,
                                     BusDemandEmployeeTempMapper busDemandEmployeeTempMapper,
                                     MsgCenterSendService msgCenterSendService) {
        super(coreEmployeeImportBatchService, coreEmployeeMapper, coreEmployeeCustomerMapper, coreUserBankMapper, coreAgreementDetailMapper, threeElementsService,
                employeeSupportService, employeeCustomerSupportService, bankCardSupportService, customerChannelSupportService, agreementSigningService, epayCallingService, logService);
        this.busDemandMapper = busDemandMapper;
        this.busDemandEmployeeMapper = busDemandEmployeeMapper;
        this.busDemandEmployeeTempMapper = busDemandEmployeeTempMapper;
        this.msgCenterSendService = msgCenterSendService;
    }

    @Override
    public boolean shallProcess(@NonNull AbstractBatchPayload<CoreEmployeeImportBatch, EmployeeAdvisorTypeEnum, Object, BusDemandEmployeeTemp> advisorPayload) {
        return EmployeeAdvisorTypeEnum.DEMAND_EMPLOYEE == advisorPayload.getAdvisorTypeEnum();
    }

    @Override
    public DemandEmployeePiecePayload packPiecePayload(List<DemandEmployeeSinglePayload> singlePayloadList) {
        return new DemandEmployeePiecePayload(singlePayloadList);
    }

    @Override
    public DemandEmployeeSinglePayload packSinglePayload(BusDemandEmployeeTemp singleEntity) {
        return new DemandEmployeeSinglePayload(singleEntity);
    }

    @Override
    protected String getDocumentTypeAndNumberString(BusDemandEmployeeTemp singleEntity) {
        return singleEntity.getDocumentType() + "-" + singleEntity.getDocumentNumber();
    }

    @Override
    public void autoCompleteSingleEntity(@NonNull DemandEmployeeSinglePayload singlePayload, @NonNull String bankCard, @NonNull String mobile, @NonNull AutoCompleteFlagParser autoCompleteFlagParser) {
        singlePayload.getSingleEntity().setBankCard(bankCard);
        singlePayload.getSingleEntity().setMobile(mobile);
        singlePayload.getSingleEntity().setAutoCompleteFlag(autoCompleteFlagParser.getAutoCompleteFlag());
    }

    @Override
    public boolean doValidateBeforeSingleProcess(@NonNull DemandEmployeeSinglePayload singlePayload, @NonNull DemandEmployeePiecePayload piecePayload, @NonNull DemandEmployeeBatchPayload batchPayload) {
        // 先检查是否执行自动补全；如果取消预加载 EmployeeAdditionPreloadAdvisorImpl，则此处就得先根据证件信息查询用户
        checkAutoComplete(singlePayload, piecePayload, batchPayload, this);
        return super.doValidateBeforeSingleProcess(singlePayload, piecePayload, batchPayload);
    }

    /**
     * 人员导入的检查或导入成功后，检查接单重复
     *
     * @param singlePayload 单条数据
     * @param piecePayload  分片数据
     * @param batchPayload  批次数据
     * @return 已接单的再次导入同样作成功处理
     */
    @Override
    public boolean doExecuteOnSingleProcess(@NonNull DemandEmployeeSinglePayload singlePayload, @NonNull DemandEmployeePiecePayload piecePayload, @NonNull DemandEmployeeBatchPayload batchPayload) {
        if (super.doExecuteOnSingleProcess(singlePayload, piecePayload, batchPayload)) {
            // 人员导入成功，检查接单
            if (busDemandEmployeeMapper.selectCount(Condition.<BusDemandEmployee>wrapper()
                    .eq("demand_id", batchPayload.getDemandId())
                    .eq("employee_id", singlePayload.getCoreEmployee().getId())
                    .andNew("record_type!=2 or record_status not in (4,5)")) > 0) {
                // 已导入接单，作成功处理，但不能重复导入，暂存 failType
                singlePayload.setDemandEmployeeFailTypeEnum(DemandEmployeeFailTypeEnum.IMPORT_REPEAT);
            } else {
                singlePayload.setDemandEmployeeFailTypeEnum(DemandEmployeeFailTypeEnum.DEFAULT);
            }
            return true;
        }
        return false;
    }

    /**
     * 人员导入整个批次成功后更新 BusDemand 中保存的接单导入状态
     *
     * @param batchPayload 批次数据
     * @return true 或者抛出异常
     */
    @Override
    public boolean doSettleOnBatchProcessed(@NonNull DemandEmployeeBatchPayload batchPayload) {
        if (super.doSettleOnBatchProcessed(batchPayload)) {
            int i = busDemandMapper.updateBatchWaitingConfirm(batchPayload.getDemandId(), batchPayload.getBatchNo());
            if (i == 0) {
                // 理论上不会出现
                logService.remind("导入接单人员完成后更新接单导入状态失败，状态异常");
            }
            return true;
        }
        return false;
    }

    /**
     * 接单导入批次验证完成，无论成功与否，发送通知
     * @param batchPayload 批次数据
     * @return true 或异常
     */
    @Override
    public boolean doCleanUpOnBatchPost(@NonNull DemandEmployeeBatchPayload batchPayload) {
        super.doCleanUpOnBatchPost(batchPayload);
        msgCenterSendService.demandEmployeeVerifyFinishedNotify(batchPayload);
        return true;
    }

    @Override
    protected boolean isSingleEntityProcessed(DemandEmployeeSinglePayload singlePayload) {
        // 导入失败的状态，认为是已处理过
        return DemandEmployeeStatusEnum.IMPORT_FAIL.getCode().equals(singlePayload.getSingleEntity().getRecordStatus());
    }

    @Override
    protected void updateValidateSuccess(DemandEmployeeSinglePayload singlePayload, DemandEmployeePiecePayload piecePayload, DemandEmployeeBatchPayload batchPayload) {
        // 更新接单记录临时表
        singlePayload.getSingleEntity().setEmployeeId(singlePayload.getCoreEmployee().getId());
        singlePayload.getSingleEntity().setFailType(singlePayload.getDemandEmployeeFailTypeEnum().getCode());
        // 更新到 db
        busDemandEmployeeTempMapper.updateById(singlePayload.getSingleEntity());
    }

    @Override
    protected void updateValidateFailed(DemandEmployeeSinglePayload singlePayload, DemandEmployeePiecePayload piecePayload, DemandEmployeeBatchPayload batchPayload, String errMsg) {
        singlePayload.getSingleEntity().setRecordStatus(DemandEmployeeStatusEnum.IMPORT_FAIL.getCode());
        singlePayload.getSingleEntity().setFailReason(errMsg);
        // 更新到 db
        busDemandEmployeeTempMapper.updateById(singlePayload.getSingleEntity());
    }
}
